Skip to content

Add responsive mobile navigation#7

Merged
danielnaab merged 11 commits into
mainfrom
worktree-mobile-menu
Apr 29, 2026
Merged

Add responsive mobile navigation#7
danielnaab merged 11 commits into
mainfrom
worktree-mobile-menu

Conversation

@danielnaab

@danielnaab danielnaab commented Apr 29, 2026

Copy link
Copy Markdown
Member

Summary

On mobile-width viewports, the navigation links exceeded the screen width, overlapped the site brand, and caused horizontal scrolling. This adds a hamburger menu that collapses the nav at narrow widths.

  • Below 576px: a hamburger button opens a popover card with stacked nav links
  • Above 576px: the existing horizontal nav bar, unchanged
  • Zero JavaScript — uses the native HTML Popover API for toggle, focus management, and dismiss behavior

How it works

The <nav> element itself carries the popover="auto" attribute. At desktop, CSS overrides the browser's default popover hiding so the nav participates in the header's flex layout normally. At mobile, the nav is hidden until the hamburger button activates it into the browser's top layer as a positioned card.

Test plan

  • On iPhone (or DevTools at 375px): hamburger appears, tapping opens card with links, Escape/tap-outside dismisses
  • On desktop width: nav displays inline as before, no hamburger visible
  • Keyboard navigation: Tab to button, Enter opens menu, Escape closes
  • No horizontal overflow at any viewport width

Addresses viewport overflow on iPhone-width screens by introducing
a popover-based hamburger menu below 36rem breakpoint.
Hono JSX renders bare `popover` as `popover="true"` which relies on
the invalid-value-default behavior. Explicit "auto" is clearer.
Three fixes:
- Move display toggling to layout layer base rules (not media query
  fighting against components layer specificity)
- Use position:fixed for popover card (top-layer elements can't use
  position:absolute relative to DOM ancestors)
- Hide entire nav at mobile, show hamburger button to the right
The popover can't activate if its ancestor has display:none.
Instead, rely on the popover's natural hidden state at mobile
(UA stylesheet hides non-open popovers). Only apply display:contents
override at desktop where we want the wrapper to be transparent.
The UA stylesheet for :popover-open sets inset:0, width:fit-content,
and margin:auto which fights with our positioning. Reset with
inset:auto, width:auto, height:auto before setting our values.
- Move popover attribute onto <nav> itself (eliminates empty wrapper
  element taking up flex gap space at mobile)
- At mobile, only brand + button are visible flex children, so
  space-between puts button at right edge
- Use physical 'right' instead of 'inset-inline-end' for reliable
  positioning in the top layer
The browser applies position:fixed and other styles to [popover]
elements. At desktop we need the nav as a normal flex child, so
explicitly reset position:static, inset:auto, etc.
@danielnaab danielnaab merged commit d15b225 into main Apr 29, 2026
3 checks passed
@danielnaab danielnaab deleted the worktree-mobile-menu branch April 29, 2026 03:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant